package com.layblog.controller;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author JackLin
 * @since 2021-07-30
 */

import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.layblog.common.lang.Result;
import com.layblog.entity.User;
import com.layblog.entity.UserMessage;
import com.layblog.es.search.model.LayPostDocument;
import com.layblog.service.ElasticSearchService;
import com.google.code.kaptcha.Producer;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Controller
public class IndexController extends BaseController {

    private static final String KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY";
    @Autowired
    ElasticSearchService searchService;
    @Autowired
    private Producer producer;

    @RequestMapping({"", "/", "/index"})
    public String index() {

        IPage results = postService.paging(getPage(), null, null, null, null, "created");
        req.setAttribute("pageData", results);
        req.setAttribute("currentCategoryId", 0);
        return "index";
    }

    @GetMapping("/login")
    public String login() {
        return "auth/login";
    }


    /**
     * 用户登陆验证： login->realm(认证)->写登陆逻辑->页面shiro标签
     *
     * @param email
     * @param password
     * @return
     */
    @ResponseBody
    @PostMapping("/login")
    public Result doLogin(String email, String password) {

        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(password)) {
            return Result.fail("用户名或密码不能为空！");
        }
        AuthenticationToken token = new UsernamePasswordToken(email, SecureUtil.md5(password));

        try {

            //尝试登陆，将会调用realm的认证方法
            SecurityUtils.getSubject().login(token);

        } catch (AuthenticationException e) {
            if (e instanceof UnknownAccountException) {
                return Result.fail("用户不存在");
            } else if (e instanceof LockedAccountException) {
                return Result.fail("用户被禁用");
            } else if (e instanceof IncorrectCredentialsException) {
                return Result.fail("密码错误");
            } else {
                return Result.fail("用户认证失败");
            }
        }
        return Result.succ("登录成功", null, "/");
    }

    @GetMapping("/register")
    public String register() {
        return "auth/register";
    }

    /**
     * 图片验证码生成逻辑
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("/capthca.jpg")
    public void captcha(HttpServletResponse response) throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //生成文字验证码
        String text = producer.createText();
        //生成图片验证码
        BufferedImage image = producer.createImage(text);
        //把验证码存到shrio的session中
        SecurityUtils.getSubject().getSession().setAttribute(KAPTCHA_SESSION_KEY, text);

        ServletOutputStream outputStream = response.getOutputStream();
        ImageIO.write(image, "jpg", outputStream);
    }


    /**
     * 用户注册验证
     *
     * @param user    用户对象信息
     * @param captcha 校验验证码的正确性
     * @param repass  重复确认密码
     * @return
     */
    @ResponseBody
    @PostMapping("/register")
    public Result doRegister(User user, String captcha, String repass) {

        String kaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(KAPTCHA_SESSION_KEY);
        if (!kaptcha.equalsIgnoreCase(captcha)) {
            return Result.fail("验证码不正确");
        }
        if (repass == null || !repass.equals(user.getPassword())) {
            return Result.fail("两次输入密码不一致");
        }
        Result result = userService.register(user);
        // 注册成功之后跳转的页面
        result.setAction("/login");
        return result;
    }

    @GetMapping("/logout")
    public String logout() throws IOException {
        SecurityUtils.getSubject().logout();
        return "redirect:/";
    }

    /**
     * 新消息通知，为user_message添加一个status字段，消息状态：0未读，1已读，将状态为0的消息查询出来，
     * 就是新消息通知的数量,然后子啊头部有个数字显示未读消息的数量！！
     *
     * @return
     * @throws IOException
     */
    @ResponseBody
    @PostMapping("/message/nums/")
    public Object messageNums() throws IOException {

        int count = userMessageService.count(new QueryWrapper<UserMessage>()
                .eq("to_user_id", getProfileId())
                .eq("status", 0));

        //调用MapUtil.builder()创建一个map，最后返回map集合
        return MapUtil.builder().put("status", 0).put("count", count).build();
    }

    /**
     * 搜索方法接口
     *
     * @param current
     * @param size
     * @param q
     * @return
     */
    @RequestMapping("/search")
    public String search(@RequestParam(defaultValue = "1") Integer current,
                         @RequestParam(defaultValue = "10") Integer size,
                         String q) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = getPage();
        IPage<LayPostDocument> pageResult = searchService.query(page, q);
        req.setAttribute("pageData", pageResult);
        req.setAttribute("q", q);

        return "search";
    }

}
